package net.homeip.jcperera.nu.core.persistence;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.persistence.EntityManagerFactory;

import net.homeip.jcperera.nu.core.CoreBase;
import net.homeip.jcperera.nu.core.config.Configuration;
import net.homeip.jcperera.nu.core.msg.Logger;

import org.eclipse.persistence.config.PersistenceUnitProperties;

/**
 * <p>
 * Session Bean implementation class Persistence
 * </p>
 * <p>
 * Handles the persistence service across the framework. Holds a reference of the system's {@link EntityManagerFactory}
 * for any transaction to use when needed. This {@link EntityManagerFactory} is already configured according to the
 * properties which specify the configuration data for the database connection.
 * </p>
 * 
 * @name Persistence Bean class
 * @author julio.c.perera@gmail.com
 * @application nu
 * @since 0.1.0.0
 */

@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
@LocalBean
@ApplicationScoped
@Named(Persistence.componentName)
public class Persistence extends CoreBase implements Serializable
{
    // Required to implement Serializable interface
    private static final long    serialVersionUID = 64034983317124359L;

    // CoreBase properties, for easy use from other components, as well as logging
    public static final int      runtimeLevel     = 0;
    public static final String   moduleName       = "core";
    public static final String   componentName    = "nu_core_persistence_bean";

    // Get the log
    private final static Logger  log              = Logger.getLogger();
    
    private boolean              initialized      = false;
    private EntityManagerFactory emf;

    @EJB
    private Configuration        configuration;

    public Persistence()
    {
    }

    public void initialize()
    {
        Map<String, String> properties = new HashMap<String, String>();

        properties.put(PersistenceUnitProperties.JDBC_DRIVER, configuration.get("nu.db.class"));
        properties.put(PersistenceUnitProperties.JDBC_URL, configuration.get("nu.db.url"));
        properties.put(PersistenceUnitProperties.JDBC_USER, configuration.get("nu.db.user"));
        properties.put(PersistenceUnitProperties.JDBC_PASSWORD, configuration.get("nu.db.password"));

        emf = javax.persistence.Persistence.createEntityManagerFactory("nuejb", properties);
        initialized = true;
    }

    public void start()
    {
        log.info("Starting Persistence Service...\n");
        initialize();
    }

    public void stop()
    {
        log.info("Stopping Persistence Service...\n");
        if (emf != null && emf.isOpen()) emf.close();
    }

    public void reinitialize()
    {
        log.info("Reinitializing Persistence Service...\n");
        if (emf != null && emf.isOpen()) emf.close();
        initialize();
    }

    public EntityManagerFactory getEntityManagerFactory()
    {
        if (!initialized) initialize();
        return emf;
    }
}
